#include "mainwindow.h"
#include "initdb.h"

#include <QByteArray>
#include <QString>
#include <QLabel>
#include <QLineEdit>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QWidget>
#include <QBuffer>
#include <QDataStream>
#include <QDateTime>
#include <QtSql>
#include <QFile>
#include <QFileDialog>
#include <QTimer>
#include <QDataStream>
#include <QFileDialog>
#include <QHostAddress>
#include <QIODevice>
#include <QProgressBar>
#include <QImage>



//建立数据库
bool dbsetup = createDatabase();
const qint64 LOADBYTES = 4 * 1024; // 4 kilo-byte


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //创建主窗体;
    this->resize(600,300);   //确定主窗口尺寸
    this->setWindowTitle(tr("体检报告上传客户端"));  //创建标题栏

    //创建主布局和子布局
    QWidget *contentWidget = new QWidget(this);  //定义中心内容组件
    this->setCentralWidget(contentWidget);
    contentWidget->setStyleSheet("font-size:16px; color:#424242;");//设置文字大小颜色
    QGridLayout *Layout = new QGridLayout(this);  //主布局
    contentWidget->setLayout(Layout);   //将主布局用于中心内容

    QLabel *ipNote = new QLabel(this);
    ipNote->setText("*请填入主电脑的IP地址");
    ipNote->setStyleSheet("font-size:14px; color:#666666;");//设置文字大小颜色
    QLabel *ip = new QLabel(this);
    ip->setText("主机地址：");
    hostIPinput = new QLineEdit(this);
    saveBtn = new QPushButton(this);
    saveBtn->setText("保存");
    Layout->addWidget(ipNote,0,0);
    Layout->addWidget(ip,1,0);
    Layout->addWidget(hostIPinput,1,1);
    Layout->addWidget(saveBtn,1,2);

    QLabel *imgNote = new QLabel(this);
    imgNote->setText("请选择需要上传的报告单图片");
    imgNote->setStyleSheet("font-size:14px; color:#666666;");//设置文字大小颜色
    QLabel *imgAddress = new QLabel(this);
    imgAddress->setText("图片地址：");
    imageInput = new QLineEdit(this);
    browseBtn = new QPushButton(this);
    browseBtn->setText("选择文件");
    QLabel *sendLabel = new QLabel(this);
    sendLabel->setText("传输进度：");
    sendProg = new QProgressBar(this);
    sendProg->setMaximum(100);
    sendProg->setValue(0);
    Layout->addWidget(imgNote,2,0);
    Layout->addWidget(imgAddress,3,0);
    Layout->addWidget(imageInput,3,1);
    Layout->addWidget(browseBtn,3,2);
    Layout->addWidget(sendLabel,4,0);
    Layout->addWidget(sendProg,4,1);

    connectBtn = new QPushButton(this);
    connectBtn->setText("连接");
    sendBtn = new QPushButton(this);
    sendBtn->setText("发送");
    sendBtn->setStyleSheet("background:rgb(153,204,255);");
    sendBtn->setEnabled(false);
    cancelBtn = new QPushButton(this);
    cancelBtn->setText("取消");
    Layout->addWidget(connectBtn,5,0);
    Layout->addWidget(sendBtn,5,1);
    Layout->addWidget(cancelBtn,5,2);

    QLabel* stateTitle = new QLabel(this);
    stateTitle->setText("联网和传输状态：");
    tcpState = new QLabel(this);
    tcpState->setText("等待连接");
    Layout->addWidget(stateTitle,6,0);
    Layout->addWidget(tcpState,6,1,1,3);


    connect(saveBtn,SIGNAL(clicked()),this,SLOT(saveHostIP()));
    connect(connectBtn,SIGNAL(clicked()),this,SLOT(tcpReConnect()));

    //确定初始IP
    QSqlQuery findIp("SELECT hostIP FROM IP");
    if (findIp.first()){
        m_hostIP = findIp.value(0).toString();
    }
    qDebug()<<"find initial m_hostIP="<<m_hostIP;
    hostIPinput ->setText(m_hostIP);

    //TCP连接
    qDebug()<<"Establish TCP connection to host";
    tcpSocket = new QTcpSocket(this);
    address = QHostAddress(m_hostIP);
    port = 7778;
    tcpSocket = new QTcpSocket(this);
    tcpSocket->connectToHost(address, port, QIODevice::ReadWrite);
    qDebug()<<"tcp client state is:"<<tcpSocket->state();
    connect(tcpSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),this, SLOT(showTcpState()));

    /* 选择文件 */
    connect(browseBtn, SIGNAL(clicked()),this, SLOT(selectFile()));
       /* 发数据 */
    connect(sendBtn, SIGNAL(clicked()),this, SLOT(start_transfer()));
        /* 数据已发出 -> 继续发 */
    //connect(tcpSocket, SIGNAL(bytesWritten(qint64)),this, SLOT(continue_transfer(qint64)));
        /* socket出错 -> 错误处理 */
    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(show_error(QAbstractSocket::SocketError)));

}

MainWindow::~MainWindow()
{

}

//保存设定的IP地址到数据库
void MainWindow::saveHostIP() {
    m_hostIP = hostIPinput->text();
    qDebug()<<"m_hostIP waiting to save="<<m_hostIP;
         QString queryStr("UPDATE IP SET hostIP=");
         QString queryIP = queryStr + "'"+m_hostIP+"'";
         QSqlQuery query(queryIP);
         query.exec();
    address = QHostAddress(m_hostIP);
}

void MainWindow::tcpReConnect() {

    qDebug()<<"TCP主机地址变更，重新连接！";
    tcpSocket->close();
    QSqlQuery findIp("SELECT hostIP FROM IP");
    findIp.exec();
    if (findIp.first()){
        m_hostIP = findIp.value(0).toString();
    }
    address = QHostAddress(m_hostIP);
    port = 7778;
    qDebug()<<"find initial m_hostIP="<<m_hostIP;
    tcpSocket->connectToHost(address, port, QIODevice::ReadWrite);
}


void MainWindow::showTcpState() {              //反应TCP连接状态
    qDebug()<<"show state function:"<<tcpSocket->state();
    QString m_tcpState;
           if (tcpSocket->state()== QAbstractSocket::UnconnectedState){
                m_tcpState="TCP主机未连接";
                //tcpSocket->connectToHost(address, port, QIODevice::ReadWrite);
                //qDebug()<<"执行TCP重连动作";
           }else if (tcpSocket->state()== QAbstractSocket::HostLookupState){
               m_tcpState="TCP主机正在查询";
           }else if (tcpSocket->state()== QAbstractSocket::ConnectingState){
               m_tcpState="TCP主机正在连接";
           }else if (tcpSocket->state()== QAbstractSocket::ConnectedState){
               m_tcpState="TCP主机已连接";
           }else if (tcpSocket->state()== QAbstractSocket::BoundState){
               m_tcpState="BoundState";
           }else if (tcpSocket->state()== QAbstractSocket::ClosingState){
               m_tcpState="TCP正在关闭";
           }else if (tcpSocket->state()== QAbstractSocket::ListeningState){
               m_tcpState="TCP正在侦听";
           }else {
               m_tcpState="TCP状态未知";
           }
   qDebug()<<"m_tcpState="<<m_tcpState;
   tcpState->setText(m_tcpState);
   if (m_tcpState == "TCP主机未连接"){
       tcpState->setStyleSheet("color:#cc0000;");
   }else {
       tcpState->setStyleSheet("color:#0033cc;");
   }

}

/*--- 点击选择按钮 ---*/
void MainWindow::selectFile()
{
    qDebug()<<"select file";
    /* 开文件选择窗选文件，返回带路径文件名 */
    fileName = QFileDialog::getOpenFileName(this,tr("打开文件"),"/",tr("Image Files(*.png *.jpg *.bmp *.tif)"));
    if(!fileName.isEmpty())
    {
        imageInput->setText(fileName);
        sendBtn->setEnabled(true);
        sendProg->setValue(0);
    }

}

/*--- 点击发送按钮 ---*/
void MainWindow::sendFile()
{
    sentBytes = 0;
    sendBtn->setEnabled(false);
    cancelBtn->setEnabled(true);
}

/*--- 开始传送 ---*/
void MainWindow::start_transfer()
{
    qDebug()<<"start transfer";
    file = new QFile(fileName);
    if(!file->open(QFile::ReadOnly))
    {
        imageInput->setText(QString("文件打开出错"));
        qDebug() << "*** start_transfer(): File-Open-Error";
        return;
    }

    sendProg->setValue(0);
    tcpState->setText(QString("开始传送文件!"));

    //获取去除路径的纯文件名
    QString fName = fileName.right(fileName.size() - fileName.lastIndexOf('/') - 1);
    qDebug()<<"fName:"<<fName;

    //将图片文件存到buffer里
    QByteArray imgByte;
    while(!file->atEnd()){
        imgByte = file->readAll();   //现将文件内容读到byteArray里
    }
    QImage img;
    img.loadFromData(imgByte);       //再将byteArray的内容加载到QImage里

    QBuffer buffer;
    buffer.open(QIODevice::ReadWrite);
    img.save(&buffer,"JPG");          //再将QImage的内容放到buffer里
    sendProg->setValue(20);

    //TCP传输图片
    QByteArray dataStr;
    QDataStream out(&dataStr,QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_3);
    out << qint32(buffer.size())<<QString(fName)<<buffer.data();  //依次发送文件尺寸、文件名、文件数据
    sendProg->setValue(50);
    fileBytes = buffer.size();
    qDebug()<<"pic size="<<buffer.size();
    qint64 sent = tcpSocket->write(dataStr);
    if (sent >= fileBytes){
      sendProg->setValue(100);
      tcpState->setText("文件传输完成");
      dataStr.resize(0);
    }


 }

/*--- 继续传输 ---*/
void MainWindow::continue_transfer(qint64 sentSize)
{
    qDebug()<<"continue_transfer，已传输的文件部分："<<sentSize;
    sentBytes += sentSize;
    sendProg->setValue(sentBytes);

    /* 全部发送完 */
    if(sentBytes == fileBytes)
    {
        tcpState->setText(QString("文件传输完毕!"));
        sentBytes = 0;
    }
}

/*--- 出错处理 ---*/
void MainWindow::show_error(QAbstractSocket::SocketError)
{
    qDebug() << "*** Socket Error";
    tcpSocket->close();
    tcpState->setText(QString("*** SOCKET ERROR, RESEND LATER"));
    sendBtn->setEnabled(true);
    sendProg->reset(); // 进度条归零
    fileName.clear();
}
